/**
 * 
 */
package adnotatio.server.impl;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletConfig;

import org.w3c.dom.Document;

import adnotatio.common.data.IPropertiesContainer;
import adnotatio.common.xml.SerializationUtil;
import adnotatio.common.xml.XMLDocument;
import adnotatio.server.DOMUtil;
import adnotatio.server.xml.dom.DomXmlDocument;

/**
 * @author kotelnikov
 */

class Provider {

    protected ServletConfig fConfig;

    public Provider(ServletConfig config) {
        fConfig = config;
    }

    /**
     * Returns an input stream for the resource with the given name
     * 
     * @param name the name of the resource to return
     * @return an input stream for the resource with the given name
     */
    private InputStream getResourceStream(String name) {
        Class<?> cls = getClass();
        String path = cls.getPackage().getName();
        path = path.replace('.', '/');
        path = "/" + path;
        path += "/" + name;
        return cls.getResourceAsStream(path);
    }

    protected Document readDocument(String name) throws IOException {
        InputStream input = getResourceStream(name);
        try {
            return DOMUtil.readXML(input);
        } catch (Exception e) {
            throw new IOException(e);
        } finally {
            input.close();
        }
    }

    protected Document readDocument(
        String name,
        Map<String, String> replacements) throws IOException {
        String str = readResource(name);
        for (Map.Entry<String, String> entry : replacements.entrySet()) {
            String from = entry.getKey();
            String to = entry.getValue();
            str = str.replace(from, to);
        }
        StringReader reader = new StringReader(str);
        try {
            return DOMUtil.readXML(reader);
        } catch (Exception e) {
            throw new IOException(e);
        } finally {
            reader.close();
        }
    }

    protected List<IPropertiesContainer> readPropertiesContainerList(String name)
        throws IOException {
        Document doc = readDocument(name);
        XMLDocument d = new DomXmlDocument(doc);
        List<IPropertiesContainer> list = new ArrayList<IPropertiesContainer>();
        SerializationUtil.deserializePropertiesList(d.getRootElement(), list);
        return list;
    }

    protected String readResource(String name) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        readResource(name, out);
        return new String(out.toByteArray(), "UTF-8");
    }

    protected void readResource(String name, OutputStream out)
        throws IOException {
        InputStream input = getResourceStream(name);
        try {
            try {
                byte[] buf = new byte[1024 * 10];
                int len;
                while ((len = input.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
            } finally {
                out.flush();
            }
        } finally {
            input.close();
        }
    }

}
